﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.MainModule.Orders;
using Domain.MainModule.Entities;
using Domain.Core;
using Domain.Core.Specification;

namespace Application.MainModule.OrderManagement
{
     public class OrderManagementService: IOrderManagementService
    {
        #region Members

        IOrderRepository _OrderRepository;

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor for OrderService
        /// </summary>
        /// <param name="orderRepository">OrderRepository dependency, usually this is resolver with IoC</param>
        public OrderManagementService(IOrderRepository orderRepository)
        {
            if (orderRepository == (IOrderRepository)null)
                throw new ArgumentNullException(Resources.Messages.exception_DependenciesAreNotInitialized);

            _OrderRepository = orderRepository;
        }

        #endregion

        public void AddOrder(Order order)
        {
            IUnitOfWork unitOfWork = _OrderRepository.UnitOfWork as IUnitOfWork;
            _OrderRepository.Add(order);
            unitOfWork.Commit();
        }

        public void ChangeOrder(Order order)
        {
            IUnitOfWork unitOfWork = _OrderRepository.UnitOfWork as IUnitOfWork;
            _OrderRepository.Modify(order);
            unitOfWork.CommitAndRefreshChanges();
        }

        public void RemoveOrder(Order order)
        {
            if (order == (Order)null)
            {
                throw new ArgumentNullException("order");
            }

            IUnitOfWork unitOfWork = _OrderRepository.UnitOfWork as IUnitOfWork;
            _OrderRepository.Remove(order);
            unitOfWork.CommitAndRefreshChanges();
        }


        #region IDisposable

        /// <summary>
        /// Dispose associated context with this domain service
        /// </summary>
        public void Dispose()
        {
            if (_OrderRepository != null
                &&
                _OrderRepository.UnitOfWork != null)
            {
                _OrderRepository.UnitOfWork.Dispose();
            }
        }

        #endregion

        public List<Order> FindPagedOrders(int pageIndex, int pageCount)
        {
            if (pageIndex < 0)
            {
                throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex");
            }

            if (pageCount <= 0)
            {
                throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount");
            }

            Specification<Order> spec = new TrueSpecification<Order>();
            return _OrderRepository.GetPagedElements(pageIndex, pageCount, c => c.OrderId, spec, true).ToList();

        }


        public Order FindOrderById(Guid orderId)
        {
            OrderOrderIdSpecification spec = new OrderOrderIdSpecification(orderId);
            return _OrderRepository.FindOrder(spec);
        }
    }
}
